﻿using Sdk.Converts;
using Sdk.FileReader;
using Sdk.Converts;
using Sdk.FileReader;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Sdk
{
    public class DocConverter : IDisposable
    {
        
        public DocConverterOptions ConvertOptions { get; set; } = new DocConverterOptions();

        public FileReadOptions ReadOptions { get; set; } = new FileReadOptions();

        public Stream? Input { get; set; }

        public Stream? Target { get; set; }

        public string InputFile { get; set; } = "";

        public ISQLConvert SQLConvert { get; set; } = new MySQLConvert();

        public IFileReader FileReader { get; set; } = new DocxReader();

        public DbTypeEnum DbType { get; set; } = DbTypeEnum.MySql;


        //protected List<TableInfo> tableInfos = new List<TableInfo>();

        public DocConverter() 
        {
        
        }

        public DocConverter SetDocFileType(InputFileTypeEnum inputFileType)
        {
            switch (inputFileType)
            {
                case InputFileTypeEnum.Docx:
                    FileReader = new DocxReader();
                    break;
                case InputFileTypeEnum.Markdown:
                    FileReader = new MarkdownReader();
                    break;
                default:
                    break;
            }

            return this;
        }

        public DocConverter SetInput(Stream stm, InputFileTypeEnum inputFileType = InputFileTypeEnum.Docx)
        {
            Input = stm;
            SetDocFileType(inputFileType);
            return this;
        }

        public DocConverter SetInputFile(string input, InputFileTypeEnum inputFileType = InputFileTypeEnum.Docx)
        {
            if (string.IsNullOrEmpty(input)) throw new ArgumentNullException("input");
            InputFile = Path.GetFullPath(input);
            if (!File.Exists(InputFile)) throw new FileNotFoundException();
            Input = new FileStream(input, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

            SetDocFileType(inputFileType);

            return this;
        }

        public DocConverter SetOutputFile(string output)
        {
            var path = Path.GetFullPath(output);
            Target = new FileStream(path, FileMode.Create);
            return this;
        }

        public DocConverter SetOutput(Stream stm)
        {
            Target = stm;
            return this;
        }

        public DocConverter SetEngine(string value)
        {
            ConvertOptions.DbEngine = value;
            return this;
        }

        public DocConverter SetDbCharSet(string value)
        {
            ConvertOptions.DbCharSet = value;
            return this;
        }

        public DocConverter WithDrop(bool value = true)
        {
            ConvertOptions.IsWithDrop = value;
            return this;
        }

        public DocConverter SetDbType(DbTypeEnum dbType) 
        {
            DbType = dbType;
            switch (dbType)
            {
                case DbTypeEnum.MySql:
                    SQLConvert = new MySQLConvert();
                    break;
                case DbTypeEnum.Oracle:
                    SQLConvert = new OracleConvert();
                    break;
                case DbTypeEnum.SqlServer:
                    SQLConvert = new SqlServerConvert();
                    break;
                default:
                    break;
            }
            return this;
        }

        public DocConverter SetTableNameSplitChar(string chr)
        {
            ReadOptions.TableNameSplitChar = chr;
            return this;
        }

        public string ToSQL()
        {
            if (Input == null)
            {
                throw new Exception("未设置输入对象");
            }
            if (Target == null)
            {
                throw new Exception("未设置输出对象");
            }

            var readReslut = FileReader.ReadDoc(Input, ReadOptions);
            string txt = SQLConvert.ToSQL(readReslut, ConvertOptions);
            var data = Encoding.UTF8.GetBytes(txt);
            Target.Write(data, 0, data.Length);
            Target.Seek(0, SeekOrigin.Begin);
            return txt;
        }

        public ReadDocResult ReadFile()
        {
            if (Input == null)
            {
                throw new Exception("未设置输入对象");
            }
            return FileReader.ReadDoc(Input, ReadOptions);
        }

        //public void ToCls()
        //{

        //}

        public void Dispose()
        {
            //throw new NotImplementedException();
            if (Input != null)
            {
                Input.Close();
                Input.Dispose();
                Input = null;
            }

            if (Target != null)
            {
                Target.Close();
                Target.Dispose();
                Target = null;
            }
        }
    }
}
